﻿using System.Buffers;

namespace GCC.Container.Abstracts
{
    /// <summary>
    /// websocket 客户端抽象
    /// </summary>
    public abstract class AbsWebsocketDataClient<T> : AbsWebsocketClient, IDisposable
    {

        /// <summary>
        /// 日志对象
        /// </summary>
        protected readonly AbsGCCLogger _logger;
        /// <summary>
        /// 上下文
        /// </summary>
        public AbsGCCContext Context { get; init; }

        /// <summary>
        /// 当收到文本消息回调
        /// </summary>
        public event Action<T>? OnGotTextMessage;
        /// <summary>
        /// 当销毁时
        /// </summary>
        public event Action<string>? OnDisposing;
        /// <summary>
        /// 内存池
        /// </summary>
        private readonly MemoryPool<byte> _memoryPool = MemoryPool<byte>.Shared;
        /// <summary>
        /// 取消token
        /// </summary>
        private readonly CancellationTokenSource _cancellToken = new();
        /// <summary>
        /// 是否已经销毁
        /// </summary>
        private bool _disposed;


        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="logger">日志</param>
        public AbsWebsocketDataClient(AbsGCCContext context, AbsGCCLogger logger)
        {
            Context = context;
            _logger = logger;
        }
        /// <summary>
        /// 析构函数
        /// </summary>
        ~AbsWebsocketDataClient()
        {
            Dispose(false);
        }

        /// <summary>
        /// 销毁模型
        /// </summary>
        /// <param name="flag">是否是用户主动调用</param>
        protected virtual void Dispose(bool flag)
        {
            if (_disposed)
            {
                return;
            }
            _disposed = true;

            OnDisposing?.Invoke(this.ID);
            try
            {
                _cancellToken.Cancel();
                _cancellToken.Dispose();
                _memoryPool.Dispose();
            }
            catch (Exception ex)
            {
                _logger.Error("GCCWSInfo dispose error.", exception: ex);
            }
        }

        /// <summary>
        /// 销毁模型
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 启动服务
        /// </summary>
        /// <returns></returns>
        public abstract Task StartJob();

        /// <summary>
        /// 发送文本消息
        /// </summary>
        /// <param name="text"></param>
        public abstract void SendTextMessage(string text);

        /// <summary>
        /// 当收到消息时
        /// </summary>
        /// <param name="data">缓冲区</param>
        protected void GotTextMessage(T data)
        {
            OnGotTextMessage?.Invoke(data);
        }
    }
}
